"""
数据库配置和模型定义
"""
import mysql.connector
from mysql.connector import pooling
from sqlalchemy import create_engine, Column, Integer, String, Text, DateTime, Float, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
from typing import Optional
import logging

from .settings import MYSQL_CONFIG

# 创建数据库连接池
def create_connection_pool():
    """创建MySQL连接池"""
    try:
        pool_config = {
            "pool_name": "vector_system_pool",
            "pool_size": 10,
            "pool_reset_session": True,
            **MYSQL_CONFIG
        }
        return pooling.MySQLConnectionPool(**pool_config)
    except Exception as e:
        logging.error(f"创建数据库连接池失败: {e}")
        return None

# 创建SQLAlchemy引擎
def create_sqlalchemy_engine():
    """创建SQLAlchemy引擎"""
    try:
        import urllib.parse
        
        # URL编码密码中的特殊字符
        encoded_password = urllib.parse.quote_plus(MYSQL_CONFIG['password'])
        
        connection_string = (
            f"mysql+mysqlconnector://{MYSQL_CONFIG['user']}:{encoded_password}"
            f"@{MYSQL_CONFIG['host']}:{MYSQL_CONFIG['port']}/{MYSQL_CONFIG['database']}"
            f"?charset={MYSQL_CONFIG['charset']}"
        )
        return create_engine(connection_string, pool_size=10, max_overflow=20)
    except Exception as e:
        logging.error(f"创建SQLAlchemy引擎失败: {e}")
        return None

# 创建基类
Base = declarative_base()

# 文件元数据模型
class FileMetadata(Base):
    """文件元数据表"""
    __tablename__ = "file_metadata"
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    file_id = Column(String(64), unique=True, nullable=False, comment="文件唯一ID")
    filename = Column(String(255), nullable=False, comment="文件名")
    file_path = Column(String(500), nullable=False, comment="文件路径")
    file_size = Column(Integer, nullable=False, comment="文件大小(字节)")
    file_type = Column(String(20), nullable=False, comment="文件类型")
    mime_type = Column(String(100), comment="MIME类型")
    
    # 处理状态
    is_processed = Column(Boolean, default=False, comment="是否已处理")
    is_vectorized = Column(Boolean, default=False, comment="是否已向量化")
    chunk_count = Column(Integer, default=0, comment="分块数量")
    vector_count = Column(Integer, default=0, comment="向量数量")
    
    # 元数据
    title = Column(String(255), comment="文档标题")
    author = Column(String(255), comment="作者")
    created_time = Column(DateTime, comment="创建时间")
    modified_time = Column(DateTime, comment="修改时间")
    
    # 系统字段
    upload_time = Column(DateTime, default=datetime.now, comment="上传时间")
    process_time = Column(DateTime, comment="处理时间")
    status = Column(String(20), default="pending", comment="状态")
    error_message = Column(Text, comment="错误信息")
    
    # 标签和分类
    tags = Column(Text, comment="标签(JSON格式)")
    category = Column(String(100), comment="分类")
    
    # 索引
    __table_args__ = (
        {"comment": "文件元数据表"}
    )

# 向量块模型
class VectorChunk(Base):
    """向量块表"""
    __tablename__ = "vector_chunks"
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    chunk_id = Column(String(64), unique=True, nullable=False, comment="块唯一ID")
    file_id = Column(String(64), nullable=False, comment="文件ID")
    chunk_index = Column(Integer, nullable=False, comment="块索引")
    
    # 内容
    content = Column(Text, nullable=False, comment="文本内容")
    content_length = Column(Integer, nullable=False, comment="内容长度")
    
    # 向量信息
    vector_id = Column(String(64), comment="Milvus中的向量ID")
    embedding_model = Column(String(100), comment="嵌入模型")
    
    # 位置信息
    page_number = Column(Integer, comment="页码")
    start_position = Column(Integer, comment="开始位置")
    end_position = Column(Integer, comment="结束位置")
    
    # 元数据
    chunk_type = Column(String(20), default="text", comment="块类型")
    language = Column(String(10), comment="语言")
    
    # 系统字段
    created_time = Column(DateTime, default=datetime.now, comment="创建时间")
    updated_time = Column(DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")
    
    # 索引
    __table_args__ = (
        {"comment": "向量块表"}
    )

# 检索历史模型
class SearchHistory(Base):
    """检索历史表"""
    __tablename__ = "search_history"
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    search_id = Column(String(64), unique=True, nullable=False, comment="检索ID")
    query = Column(Text, nullable=False, comment="查询内容")
    query_type = Column(String(20), default="semantic", comment="查询类型")
    
    # 结果信息
    result_count = Column(Integer, default=0, comment="结果数量")
    search_time = Column(Float, comment="检索耗时(秒)")
    
    # 用户信息
    user_id = Column(String(64), comment="用户ID")
    session_id = Column(String(64), comment="会话ID")
    
    # 系统字段
    created_time = Column(DateTime, default=datetime.now, comment="创建时间")
    ip_address = Column(String(45), comment="IP地址")
    user_agent = Column(Text, comment="用户代理")
    
    # 索引
    __table_args__ = (
        {"comment": "检索历史表"}
    )

# 系统配置模型
class SystemConfig(Base):
    """系统配置表"""
    __tablename__ = "system_config"
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    config_key = Column(String(100), unique=True, nullable=False, comment="配置键")
    config_value = Column(Text, comment="配置值")
    config_type = Column(String(20), default="string", comment="配置类型")
    description = Column(Text, comment="配置描述")
    
    # 系统字段
    created_time = Column(DateTime, default=datetime.now, comment="创建时间")
    updated_time = Column(DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")
    
    # 索引
    __table_args__ = (
        {"comment": "系统配置表"}
    )

# 数据库管理器
class DatabaseManager:
    """数据库管理器"""
    
    def __init__(self):
        self.engine = create_sqlalchemy_engine()
        self.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)
        self.connection_pool = create_connection_pool()
    
    def get_session(self):
        """获取数据库会话"""
        return self.SessionLocal()
    
    def get_connection(self):
        """获取数据库连接"""
        if self.connection_pool:
            return self.connection_pool.get_connection()
        return None
    
    def create_tables(self):
        """创建所有表"""
        try:
            Base.metadata.create_all(bind=self.engine)
            logging.info("数据库表创建成功")
        except Exception as e:
            logging.error(f"创建数据库表失败: {e}")
            raise
    
    def drop_tables(self):
        """删除所有表"""
        try:
            Base.metadata.drop_all(bind=self.engine)
            logging.info("数据库表删除成功")
        except Exception as e:
            logging.error(f"删除数据库表失败: {e}")
            raise

# 全局数据库管理器实例
db_manager = DatabaseManager()
